﻿using System;
using System.Linq;
using MethodCaching.Weaving;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Mono.Cecil;
using SampleLibrary;

namespace MethodCaching.Tests
{
    [TestClass]
    public class WeaverTests
    {
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }
        
        [TestMethod]
        public void ResolveMethodsDecoratedWithCachedAttribute()
        {
            int methodCount =
                typeof (SampleClass).GetMethods().Where(m => m.IsDefined(typeof (CachedAttribute), true)).Count();
            
            var moduleDefinition = ModuleDefinition.ReadModule("SampleLibrary.dll");
            var type = moduleDefinition.Types.Where(t => t.Name.StartsWith("SampleClass")).FirstOrDefault();
            IMethodSelector methodSelector = new AttributeMethodSelector();
            var methods = methodSelector.Select(type);
            Assert.AreEqual(methodCount,methods.Count());
        }

        [TestMethod]
        public void ResolveTypesDecoratedWithEnableCachingAttribute()
        {
            int typeCount = typeof (SampleClass).Assembly.GetTypes().Where(t => t.IsDefined(typeof (EnableMethodCachingAttribute), true)).Count();            
            var moduleDefinition = ModuleDefinition.ReadModule("SampleLibrary.dll");
            ITypeSelector attributeTypeSelector = new AttributeTypeSelector();
            var types = attributeTypeSelector.Select(moduleDefinition);                        
            Assert.AreEqual(typeCount, types.Count());
        }
        

        [TestMethod]
        public void MustPassPeVerify()
        {
            var assemblyWeaver = new AssemblyWeaver(new TypeWeaver(new AttributeMethodSelector()), new AttributeTypeSelector());
            assemblyWeaver.Weave("SampleLibrary.dll");
            AssemblyVerifier.Verify("SampleLibrary.dll");         
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ThrowArgumentNullExceptionWhenTypeWeaverOrTypeSelectorIsNull()
        {
            var assemblyWeaver = new AssemblyWeaver(null, null);
        }
      
    }
}
